package com.zx.system.block.service.impl;

import com.zx.core.context.TenantContextHolder;
import com.zx.core.enums.StatusEnum;
import com.zx.core.wrapper.ListWrapper;
import com.zx.core.wrapper.ResponseWrapper;
import com.zx.security.block.uitls.SecurityUtils;
import com.zx.system.block.dao.SysDeptMapper;
import com.zx.system.block.mapstruct.DeptMapStructMapper;
import com.zx.system.block.model.SysDept;
import com.zx.system.block.param.DeptParam;
import com.zx.system.block.service.ISysDeptService;
import com.zx.system.block.utils.SystemNoUtils;
import com.zx.system.block.vo.SysDeptVO;
import com.zx.system.block.vo.TreeVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * description: 业务层部门服务实现 <br>
 * create: 2024-09-22 13:26
 * </p>
 *
 * @author zhou  xun
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SysDeptServiceImpl implements ISysDeptService {
    private final SysDeptMapper sysDeptMapper;

    /**
     * 获取部门树
     *
     * @param deptParam 部门信息
     * @return {@link List < TreeVo >}
     * @author zhou  xun
     * @since 2024-09-22
     */
    @Override
    public ListWrapper<TreeVO> getDeptTree(DeptParam deptParam) {
        ListWrapper<TreeVO> result = new ListWrapper<>();
        SysDept sysDept = DeptMapStructMapper.INSTANCE.deptParamToSysDept(deptParam);
        // 添加租户过滤
        sysDept.setTenantId(TenantContextHolder.getTenantId());
        List<SysDept> sysDeptList = sysDeptMapper.selectDeptList(sysDept);
        List<TreeVO> treeVOList = convertToTreeVo(sysDeptList);
        result.setData(treeVOList);
        return result;
    }

    /**
     * 获取部门信息Map 用于部门信息匹配
     *
     * @return {@link Map <String,SysDept>}
     * @author zhou  xun
     * @since 2024-10-01
     */
    @Override
    public Map<String, SysDept> getDept() {
        Map<String, SysDept> map = new HashMap<>();
        SysDept queryDept = new SysDept();
        queryDept.setTenantId(TenantContextHolder.getTenantId());
        List<SysDept> sysDeptList = sysDeptMapper.selectDeptList(queryDept);
        if (null != sysDeptList && !sysDeptList.isEmpty()) {
            //将列表转换为 Map
            for (SysDept dept : sysDeptList) {
                map.putIfAbsent(dept.getId(), dept);
            }
        }
        return map;
    }

    /**
     * 根据部门ID查询部门信息
     *
     * @param deptId 部门ID
     * @return {@link SysDept} 部门信息
     * @author zhou  xun
     * @since 2024-10-19
     */
    @Override
    public SysDept selectDeptById(String deptId) {
        return sysDeptMapper.selectByPrimaryKey(deptId);
    }

    /**
     * 查询部门列表
     *
     * @param deptParam 部门信息
     * @return {@link ListWrapper<SysDept>}
     * @author zhou  xun
     * @since 2024-10-02
     */
    @Override
    public ListWrapper<SysDept> selectDeptList(DeptParam deptParam) {
        ListWrapper<SysDept> result = new ListWrapper<>();
        SysDept sysDept = DeptMapStructMapper.INSTANCE.deptParamToSysDept(deptParam);
        // 添加租户过滤
        sysDept.setTenantId(TenantContextHolder.getTenantId());
        List<SysDept> sysDeptList = sysDeptMapper.selectDeptList(sysDept);
        result.setData(sysDeptList);
        return result;
    }

    /**
     * 查询部门列表
     *
     * @param deptParam 部门信息
     * @return {@link ListWrapper<SysDeptVO>}
     * @author zhou  xun
     * @since 2024-10-02
     */
    @Override
    public ListWrapper<SysDeptVO> selectDeptVOList(DeptParam deptParam) {
        ListWrapper<SysDeptVO> result = new ListWrapper<>();
        // 获取部门列表
        ListWrapper<SysDept> listWrapper = selectDeptList(deptParam);

        // 验证请求是否成功或数据是否为空
        if (listWrapper.verifyFail()) {
            result.fail(listWrapper.getMsg());
            return result;
        }

        if (null != listWrapper.getData() || !listWrapper.getData().isEmpty()) {
            // 获取部门信息
            Map<String, SysDept> deptMap = getDept();
            // 转换并处理数据
            List<SysDeptVO> processedData = listWrapper.getData().stream()
                    .map(item -> {
                        // 使用MapStruct进行基础属性转换和描述性字段设置
                        SysDeptVO sysDeptVO = DeptMapStructMapper.INSTANCE.sysDeptToSysDeptVO(item);

                        // 设置父部门名称
                        String parentId = item.getParentId();
                        if (null != parentId && !parentId.isEmpty()) {
                            SysDept sysDept = deptMap.get(parentId);
                            if (null != sysDept) {
                                sysDeptVO.setParentName(sysDept.getName());
                            }
                        }

                        return sysDeptVO;
                    })
                    .collect(Collectors.toList());
            result.setData(processedData);
        }
        return result;
    }

    /**
     * 新增部门
     *
     * @param deptParam 部门信息
     * @return {@link ResponseWrapper}
     * @author zhou  xun
     * @since 2024-10-03
     */
    @Override
    public ResponseWrapper addDept(DeptParam deptParam) {
        ResponseWrapper result = new ResponseWrapper();
        try {
            if (null != deptParam.getParentId()) {
                // 验证父级部门是否存在
                SysDept selectByParentId = sysDeptMapper.selectByPrimaryKey(deptParam.getParentId());
                if (null == selectByParentId) {
                    result.fail("传入的父级部门信息不存在!");
                    return result;
                }
                StatusEnum parentStatusE = StatusEnum.getEnumByCode(selectByParentId.getStatus());
                if (null == parentStatusE) {
                    result.fail("传入的父级部门状态错误!");
                    return result;
                }
                if (StatusEnum.DISABLE.getCode().equals(parentStatusE.getCode())) {
                    result.fail("传入的父级部门已停用!");
                    return result;
                }
            }
            //验证部门名称唯一性
            List<SysDept> sysDeptList = sysDeptMapper.selectDeptByParentId(deptParam.getParentId());
            if (null != sysDeptList && !sysDeptList.isEmpty()) {
                if (sysDeptList.stream().anyMatch(dept -> dept.getName().equals(deptParam.getName()))) {
                    result.fail("已存在相同部门名称!");
                    return result;
                }
            }
            // 验证部门状态
            StatusEnum statusEnum = StatusEnum.getEnumByCode(deptParam.getStatus());
            if (null == statusEnum) {
                result.fail("传入的部门状态错误!");
                return result;
            }
            SysDept sysDept = DeptMapStructMapper.INSTANCE.deptParamToSysDept(deptParam);
            // 设置id
            sysDept.setId(SystemNoUtils.generateSystemId());
            // 设置租户ID
            sysDept.setTenantId(TenantContextHolder.getTenantId());
            sysDept.setCreateBy(SecurityUtils.getUserId());
            sysDept.setCreateTime(LocalDateTime.now());
            sysDeptMapper.insert(sysDept);
        } catch (Exception e) {
            log.error("新增部门时发生错误", e);
            result.fail("新增部门时发生错误: " + e.getMessage());
        }
        return result;
    }

    /**
     * 编辑部门
     *
     * @param deptParam 部门信息
     * @return {@link ResponseWrapper}
     * @author zhou  xun
     * @since 2024-10-03
     */
    @Override
    public ResponseWrapper editDept(DeptParam deptParam) {
        ResponseWrapper result = new ResponseWrapper();
        try {
            // 验证部门是否存在
            SysDept selectByPrimaryKey = sysDeptMapper.selectByPrimaryKey(deptParam.getId());
            if (null == selectByPrimaryKey) {
                result.fail("传入的部门信息不存在!");
                return result;
            }
            if (null != deptParam.getParentId()) {
                // 验证父级部门是否存在
                SysDept selectByParentId = sysDeptMapper.selectByPrimaryKey(deptParam.getParentId());
                if (null == selectByParentId) {
                    result.fail("传入的父级部门信息不存在!");
                    return result;
                }
            }
            //验证部门名称唯一性
            List<SysDept> sysDeptList = sysDeptMapper.selectDeptByParentId(deptParam.getParentId());
            if (null != sysDeptList && !sysDeptList.isEmpty()) {
                if (sysDeptList.stream().anyMatch(dept -> dept.getName().equals(deptParam.getName())
                        && !dept.getId().equals(deptParam.getId()))) {
                    result.fail("已存在相同部门名称!");
                    return result;
                }
            }

            // 验证部门状态
            StatusEnum statusEnum = StatusEnum.getEnumByCode(deptParam.getStatus());
            if (null == statusEnum) {
                result.fail("传入的部门状态错误!");
                return result;
            }
            SysDept sysDept = DeptMapStructMapper.INSTANCE.deptParamToSysDept(deptParam);
            sysDept.setUpdateBy(SecurityUtils.getUserId());
            sysDept.setUpdateTime(LocalDateTime.now());
            sysDeptMapper.updateByPrimaryKeySelective(sysDept);
        } catch (Exception e) {
            log.error("编辑部门时发生错误", e);
            result.fail("编辑部门时发生错误: " + e.getMessage());
        }
        return result;
    }

    /**
     * 编辑部门状态
     *
     * @param id     部门信息
     * @param status 部门状态
     * @return {@link ResponseWrapper}
     * @author zhou  xun
     * @since 2024-10-03
     */
    @Override
    public ResponseWrapper editDeptStatus(String id, Integer status) {
        ResponseWrapper result = new ResponseWrapper();
        try {
            // 验证部门状态
            StatusEnum statusEnum = StatusEnum.getEnumByCode(status);
            if (null == statusEnum) {
                result.fail("传入的部门状态错误!");
                return result;
            }
            // 验证部门是否存在
            SysDept selectByPrimaryKey = sysDeptMapper.selectByPrimaryKey(id);
            if (null == selectByPrimaryKey) {
                result.fail("传入的部门信息不存在!");
                return result;
            }
            SysDept sysDept = new SysDept();
            sysDept.setId(id);
            sysDept.setStatus(status);
            sysDept.setUpdateBy(SecurityUtils.getUserId());
            sysDept.setUpdateTime(LocalDateTime.now());
            sysDeptMapper.updateByPrimaryKeySelective(sysDept);
        } catch (Exception e) {
            log.error("编辑部门状态时发生错误", e);
            result.fail("编辑部门状态时发生错误: " + e.getMessage());
        }
        return result;
    }


    /**
     * 删除部门
     *
     * @param deptId 部门id
     * @return {@link ResponseWrapper}
     * @author zhou  xun
     * @since 2024-10-03
     */
    @Override
    public ResponseWrapper deleteDept(String deptId) {
        ResponseWrapper result = new ResponseWrapper();
        try {
            // 验证部门是否存在
            SysDept selectByPrimaryKey = sysDeptMapper.selectByPrimaryKey(deptId);
            if (null == selectByPrimaryKey) {
                result.fail("传入的部门信息不存在!");
                return result;
            }
            List<SysDept> sysDeptList = sysDeptMapper.selectDeptByParentId(deptId);
            if (sysDeptList != null && !sysDeptList.isEmpty()) {
                result.fail("该部门下存在子部门，无法删除!");
                return result;
            }
            sysDeptMapper.deleteByPrimaryKey(deptId);
        } catch (Exception e) {
            log.error("删除部门时发生错误", e);
            result.fail("删除部门时发生错误: " + e.getMessage());
        }
        return result;
    }


    private List<TreeVO> convertToTreeVo(List<SysDept> sysDeptList) {
        //转换为前端需要的vo对象
        List<TreeVO> treeVOList = new ArrayList<>();
        if (!sysDeptList.isEmpty()) {
            sysDeptList.forEach(sysDept -> {
                TreeVO treeVo = new TreeVO();
                if (sysDept.getId() != null && !sysDept.getId().isEmpty()) {
                    treeVo.setId(sysDept.getId());
                }
                if (sysDept.getParentId() != null && !sysDept.getParentId().isEmpty()) {
                    treeVo.setParentId(sysDept.getParentId());
                }
                if (sysDept.getName() != null && !sysDept.getName().isEmpty()) {
                    treeVo.setName(sysDept.getName());
                }
                treeVOList.add(treeVo);
            });
            treeVOList.forEach(treeVo -> {
                List<TreeVO> children = treeVOList.stream()
                        .filter(item -> treeVo.getId().equals(item.getParentId()))
                        .collect(Collectors.toList());
                if (!children.isEmpty()) {
                    treeVo.setChildren(children);

                }
            });
            // 使用迭代器移除元素
            treeVOList.removeIf(treeVo -> treeVo.getParentId() != null);
        }
        return treeVOList;
    }
}
